/*
    jQuery for mocking fade in and out for Internet Explorer.
    Copyright (c) 2010 Keiji Hokamura (famteam)
    This plugin available for use in all personal or commercial projects under both MIT and GPL licenses.
 */

(function($) {
	
	var methods = {
		_getOver: function(backgroundColor, width, height, opacity, self) {
			var over = $('<div />').width(width).height(height).css('background-color', backgroundColor).fadeTo(0, opacity);
			over.css('position', 'absolute').css('top', 0).css('left', 0).appendTo(self);
			return over;
		},
		fadeIn: function(duration, easeType, completeHandler, backgroundColor, delay, width, height, self) {
			var completeCount = 0;
			var size = self.size();
			function completeMonitor() {
				if (completeCount++ == size && completeHandler != null) {
					completeHandler();
				}
			}
			completeMonitor();
			
			return self.each(function(index) {
				var target = $(this);
				var data = target.data($.mockFade.DATA);
				var fadeOver = data != null && data.over != null ? data.over : methods._getOver(backgroundColor, width, height, 1, target);
				target.show();
				fadeOver.delay(delay).fadeTo(duration, 0, function() {
					fadeOver.remove();
					completeMonitor();
				});
				data = data != null ? data : {};
				data.over = null;
				target.data($.mockFade.DATA, data);
			});
		},
		fadeOut: function(duration, easeType, completeHandler, backgroundColor, delay, width, height, self) {
			var completeCount = 0;
			var size = self.size();
			function completeMonitor() {
				if (++completeCount == size && completeHandler != null) {
					completeHandler();
				}
			}

			return self.each(function() {
				var target = $(this);
				var fadeOver = methods._getOver(backgroundColor, width, height, 0, target);
				self.show();
				fadeOver.delay(delay).fadeTo(duration, 1, function() {
					target.hide();
					fadeOver.remove();
					completeMonitor();
				});
			});
		},
		hide: function(backgroundColor, width, height, self) {
			return self.each(function() {
				var target = $(this);
				var fadeOver = methods._getOver(backgroundColor, width, height, 1, target);
				target.data($.mockFade.DATA, {
					over: fadeOver
				});
			});
		}
	};
	
	$.fn.mockFade = function(settings) {
		settings = $.extend({
			action: this.css('display') == 'none' ? $.mockFade.IN : $.mockFade.OUT,
			duration: 200,
			easeType: 'easeOutQuad',
			completeHandler: null,
			backgroundColor: '#ffffff',
			width: null,
			height: null,
			delay: 0
		}, settings);
		
		var self = $(this);
		var width = settings.width != null ? settings.width : self.width();
		var height = settings.height != null ? settings.height : self.height();

		return this.each(function() {
			switch(settings.action) {
				case $.mockFade.IN:
					return methods.fadeIn(settings.duration, settings.easeType, settings.completeHandler, settings.backgroundColor, settings.delay, width, height, $(this));
				case $.mockFade.OUT:
					return methods.fadeOut(settings.duration, settings.easeType, settings.completeHandler, settings.backgroundColor, settings.delay, width, height, $(this));
				case $.mockFade.HIDE:
					return methods.hide(settings.backgroundColor, width, height, $(this));
			}
		});
	};
	
	$.mockFade = {
		DATA: 'mock-fade-data',
		IN: 'in',
		OUT: 'out',
		HIDE: 'hide'
	};
})(jQuery);